home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / stdwin / Ports / mac / draw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-29  |  13.9 KB  |  844 lines  |  [TEXT/????]

  1. /* MAC STDWIN -- DOCUMENT DRAWING. */
  2.  
  3. /* Contents of this file:
  4.    
  5.    wchange, wscroll;
  6.    wbegindrawing, wenddrawing, _wupdate, wupdate;
  7.    text attribute manipulation (internal and external);
  8.    text measuring;
  9.    text drawing;
  10.    coordinate conversion tools;
  11.    ordinary drawing;
  12.    color stuff.
  13.    
  14.    XXX Should be split, only things used between w{begin,end}drawing
  15.    belong here.
  16.  
  17.    BEWARE OF COORDINATE SYSTEMS!
  18.    
  19.    The window's origin is not always the same.
  20.    When the aplication isn't drawing (i.e., outside w{begin,end}drawing),
  21.    the origin is (0, 0); this is necessary because the control mgr
  22.    doesn't like it otherwise.
  23.    When the application is drawing, the origin is set to win->(orgh, orgv)
  24.    so the drawing primitives don't need to do their own coordinate
  25.    transformation.
  26.    Routines called while not drawing must do their own transformations.
  27.    
  28.    XXX Routines that may be called any time are in trouble!
  29.    (There shouldn't be any.)
  30. */
  31.  
  32. #include "macwin.h"
  33. #ifdef MPW
  34. #include <Fonts.h>
  35. #endif
  36.  
  37. COLOR _w_fgcolor = blackColor;
  38. COLOR _w_bgcolor = whiteColor;
  39. static COLOR save_fgcolor, save_bgcolor;
  40.  
  41. static WINDOW *drawing;
  42. static TEXTATTR drawsaveattr;
  43. static int baseline;
  44. static int lineheight;
  45.  
  46. /* Avoid name conflicts: */
  47.  
  48. #define getfinfo getfinfo_
  49. #define wsetstyle wsetstyle_
  50.  
  51. /* Function prototypes */
  52.  
  53. STATIC void getwattr _ARGS((GrafPtr port, TEXTATTR *attr));
  54. STATIC void setwattr _ARGS((TEXTATTR *attr));
  55. STATIC void getfinfo _ARGS((void));
  56.  
  57. /* Patterns -- can't use the QuickDraw globals (sigh) */
  58.  
  59. static Pattern pat0   = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  60. static Pattern pat25  = {0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44};
  61. static Pattern pat50  = {0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa};
  62. static Pattern pat75  = {0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd};
  63. static Pattern pat100 = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  64.  
  65. void
  66. wchange(win, left, top, right, bottom)
  67.     WINDOW *win;
  68.     int left, top, right, bottom;
  69. {
  70.     Rect r;
  71.     
  72.     SetPort(win->w);
  73.     
  74.     if (drawing) dprintf("warning: wchange called while drawing");
  75.     makerect(win, &r, left, top, right, bottom);
  76.     InvalRect(&r);
  77. }
  78.  
  79. void
  80. wscroll(win, left, top, right, bottom, dh, dv)
  81.     WINDOW *win;
  82.     int left, top, right, bottom;
  83.     int dh, dv;
  84. {
  85.     Rect r;
  86.     
  87.     if (drawing) dprintf("warning: wchange called while drawing");
  88.     makerect(win, &r, left, top, right, bottom);
  89.     scrollby(win, &r, dh, dv);
  90. }
  91.  
  92. /* Scroll a rectangle (given in window coordinates) by dh, dv.
  93.    Also used from scroll.c. */
  94. /* XXX need less visible name */
  95.  
  96. void
  97. scrollby(win, pr, dh, dv)
  98.     WINDOW *win;
  99.     Rect *pr;
  100.     int dh, dv;
  101. {
  102.     RgnHandle rgn= NewRgn();
  103.     
  104.     SetPort(win->w);
  105.     
  106.     rmcaret(win);
  107.     
  108.     if (!EmptyRgn(( (WindowPeek)win->w )->updateRgn)) {
  109.         RgnHandle ur= NewRgn();
  110.         int left, top;
  111.         Rect r;
  112.         
  113.         /* Scroll the part of the update region that intersects
  114.            the scrolling area. */
  115.         CopyRgn(( (WindowPeek)win->w )->updateRgn, ur);
  116.         /* portBits.bounds is the screen in local coordinates! */
  117.         left= win->w->portBits.bounds.left;
  118.         top= win->w->portBits.bounds.top;
  119.         OffsetRgn(ur, left, top); /* Global to Local */
  120.         RectRgn(rgn, pr);
  121.         SectRgn(rgn, ur, ur);
  122.         if (!EmptyRgn(ur)) {
  123.             ValidRgn(ur);
  124.             OffsetRgn(ur, dh, dv);
  125.             SectRgn(rgn, ur, ur);
  126.             InvalRgn(ur);
  127.         }
  128.         DisposeRgn(ur);
  129.     }
  130.     
  131.     /* ScrollRect seems to work only in normal mode */
  132.     ForeColor(blackColor);
  133.     BackColor(whiteColor);
  134.     ScrollRect(pr, dh, dv, rgn);
  135.     ForeColor((short)win->fgcolor);
  136.     BackColor((short)win->bgcolor);
  137.     
  138.     InvalRgn(rgn);
  139.     
  140.     DisposeRgn(rgn);
  141. }
  142.  
  143.  
  144. /* Internal version of wupdate -- also used from event.c */
  145.  
  146. void
  147. _wupdate(win, pr)
  148.     WINDOW *win;
  149.     Rect *pr;
  150. {
  151.     RgnHandle rgn= NewRgn();
  152.     
  153.     SetPort(win->w);
  154.     
  155.     rmcaret(win);
  156.     BeginUpdate(win->w);
  157.     EraseRect(&win->w->portRect);
  158.     _wgrowicon(win);
  159.     DrawControls(win->w);
  160.     getwinrect(win, pr);
  161.     RectRgn(rgn, pr);
  162.     SectRgn(rgn, win->w->visRgn, rgn);
  163.     *pr= (*rgn)->rgnBBox;
  164.     OffsetRect(pr, win->orgh, win->orgv);
  165.     if (win->drawproc != NULL && !EmptyRect(pr)) {
  166.         wbegindrawing(win);
  167.         (*win->drawproc)(win, pr->left, pr->top, pr->right, pr->bottom);
  168.         wenddrawing(win);
  169.     }
  170.     EndUpdate(win->w);
  171.     DisposeRgn(rgn);
  172. }
  173.  
  174. /* Process an update event -- call the window's draw procedure. */
  175. /* XXX This function shouldn't be in the stdwin spec (why was it ever?) */
  176.  
  177. void
  178. wupdate(win)
  179.     WINDOW *win;
  180. {
  181.     if (win->drawproc != NULL) {
  182.         Rect r;
  183.         _wupdate(win, &r);
  184.     }
  185. }
  186.  
  187. void
  188. wbegindrawing(win)
  189.     WINDOW *win;
  190. {
  191.     Rect r;
  192.     
  193.     if (drawing != NULL) {
  194.         dprintf("warning: recursive call to wbegindrawing");
  195.         /* Fix it */
  196.         wenddrawing(drawing);
  197.     }
  198.     if (win == NULL) {
  199.         dprintf("warning: wbegindrawing(NULL) ignored");
  200.         return;
  201.     }
  202.     drawing= win;
  203.     SetPort(win->w);
  204.     SetOrigin(win->orgh, win->orgv);
  205.     rmcaret(win);
  206.     getwinrect(win, &r);
  207.     ClipRect(&r);
  208.     PenNormal();
  209.     wgettextattr(&drawsaveattr);
  210.     wsettextattr(&win->attr);
  211.     
  212.     save_fgcolor = _w_fgcolor;
  213.     save_bgcolor = _w_bgcolor;
  214.     _w_fgcolor = win->fgcolor;
  215.     _w_bgcolor = win->bgcolor;
  216.     _w_usefgcolor(_w_fgcolor);
  217.     _w_usebgcolor(_w_bgcolor);
  218. }
  219.  
  220. void
  221. wenddrawing(win)
  222.     WINDOW *win;
  223. {
  224.     Rect r;
  225.     
  226.     if (drawing == NULL) {
  227.         dprintf("warning: wenddrawing ignored while not drawing");
  228.         return;
  229.     }
  230.     if (drawing != win) {
  231.         dprintf("warning: wenddrawing ignored for wrong window");
  232.         return;
  233.     }
  234.     
  235.     _w_fgcolor = save_fgcolor;
  236.     _w_bgcolor = save_bgcolor;
  237.     _w_usefgcolor(win->fgcolor);
  238.     _w_usebgcolor(win->bgcolor);
  239.     
  240.     SetOrigin(0, 0);
  241.     SetRect(&r, -32000, -32000, 32000, 32000);
  242.     ClipRect(&r);
  243.     wsettextattr(&drawsaveattr);
  244.     drawing= NULL;
  245. }
  246.  
  247. /* Get the current text attributes of a GrafPort. */
  248.  
  249. static void
  250. getwattr(port, attr)
  251.     GrafPtr port;
  252.     TEXTATTR *attr;
  253. {
  254.     SetPort(port); /* XXX Is this necessary to validate txFont etc.? */
  255.     
  256.     attr->font= port->txFont;
  257.     attr->style= port->txFace;
  258.     attr->size= port->txSize;
  259. }
  260.  
  261. /* Start using the given text attributes in the current grafport. */
  262.  
  263. static void
  264. setwattr(attr)
  265.     TEXTATTR *attr;
  266. {
  267.     TextFont(attr->font);
  268.     TextFace(attr->style & ~TX_INVERSE);
  269.     TextSize(attr->size);
  270. }
  271.  
  272. /* Get font info and baseline from current GrafPort */
  273.  
  274. static void
  275. getfinfo()
  276. {
  277.     FontInfo finfo;
  278.     GetFontInfo(&finfo);
  279.     baseline= finfo.ascent + finfo.leading;
  280.     lineheight= baseline + finfo.descent;
  281. }
  282.  
  283. /* Initialize 'wattr'.  Uses the screen's grafport. */
  284.  
  285. int _w_font= applFont;
  286. int _w_size= 9;
  287.  
  288. void
  289. initwattr()
  290. {
  291.     TEXTATTR saveattr;
  292.     
  293.     SetPort(screen);
  294.     
  295.     getwattr(screen, &saveattr);
  296.     TextFont(_w_font);
  297.     TextSize(_w_size);
  298.     getwattr(screen, &wattr);
  299.     getfinfo();
  300.     setwattr(&saveattr);
  301. }
  302.  
  303. /* TEXT ATTRIBUTES. */
  304.  
  305. void
  306. wgettextattr(attr)
  307.     TEXTATTR *attr;
  308. {
  309.     *attr= wattr;
  310. }
  311.  
  312. void
  313. wsettextattr(attr)
  314.     TEXTATTR *attr;
  315. {
  316.     wattr= *attr;
  317.     if (drawing != NULL) {
  318.         setwattr(attr);
  319.         getfinfo();
  320.     }
  321. }
  322.  
  323. void
  324. wgetwintextattr(win, attr)
  325.     WINDOW *win;
  326.     TEXTATTR *attr;
  327. {
  328.     *attr= win->attr;
  329. }
  330.  
  331. void
  332. wsetwintextattr(win, attr)
  333.     WINDOW *win;
  334.     TEXTATTR *attr;
  335. {
  336.     win->attr= *attr;
  337.     if (drawing != NULL)
  338.         dprintf("warning: wsetwintextattr called while drawing");
  339. }
  340.  
  341. char **
  342. wlistfontnames(pat, plen)
  343.     char *pat;
  344.     int *plen;
  345. {
  346.     /* XXX not yet implemented */
  347.     *plen = 0;
  348.     return NULL;
  349. }
  350.  
  351. int
  352. wsetfont(fontname)
  353.     char *fontname;
  354. {
  355.     int ret = 1;
  356.     if (fontname == NULL || *fontname == EOS)
  357.         wattr.font= _w_font;
  358.     else {
  359.         short fnum= 0;
  360.         GetFNum(PSTRING(fontname), &fnum);
  361.         if (fnum == 0) {
  362.             dprintf("can't find font %s", fontname);
  363.             ret = 0;
  364.         }
  365.         wattr.font= fnum;
  366.     }
  367.     if (drawing != NULL) {
  368.         TextFont(wattr.font);
  369.         getfinfo();
  370.     }
  371.     return ret;
  372. }
  373.  
  374. void
  375. wsetsize(size)
  376.     int size;
  377. {
  378.     wattr.size= size;
  379.     if (drawing != NULL) {
  380.         TextSize(size);
  381.         getfinfo();
  382.     }
  383. }
  384.  
  385. void
  386. wsetstyle(face)
  387.     Style face;
  388. {
  389.     wattr.style= face;
  390.     if (drawing != NULL) {
  391.         TextFace(face & ~TX_INVERSE);
  392.         getfinfo();
  393.     }
  394. }
  395.  
  396. void
  397. wsetplain()
  398. {
  399.     wsetstyle(0);
  400. }
  401.  
  402. void
  403. wsetinverse()
  404. {
  405.     wattr.style |= TX_INVERSE;
  406. }
  407.  
  408. void
  409. wsetbold()
  410. {
  411.     wsetstyle(bold);
  412. }
  413.  
  414. void
  415. wsetitalic()
  416. {
  417.     wsetstyle(italic);
  418. }
  419.  
  420. void
  421. wsetbolditalic()
  422. {
  423.     wsetstyle(bold|italic);
  424. }
  425.  
  426. void
  427. wsetunderline()
  428. {
  429.     wsetstyle(underline);
  430. }
  431.  
  432. void
  433. wsethilite()
  434. {
  435.     wsetstyle(TX_INVERSE);
  436. }
  437.  
  438. /* TEXT MEASURING. */
  439.  
  440. int
  441. wlineheight()
  442. {
  443.     if (drawing == NULL) {
  444.         TEXTATTR saveattr;
  445.         getwattr(screen, &saveattr);
  446.         setwattr(&wattr);
  447.         getfinfo();
  448.         setwattr(&saveattr);
  449.     }
  450.     return lineheight;
  451. }
  452.  
  453. int
  454. wbaseline()
  455. {
  456.     if (drawing == NULL)
  457.         (void) wlineheight();
  458.     return baseline;
  459. }
  460.  
  461. int
  462. wtextwidth(str, len)
  463.     char *str;
  464.     int len;
  465. {
  466.     TEXTATTR saveattr;
  467.     int width;
  468.     
  469.     if (drawing == NULL) {
  470.         getwattr(screen, &saveattr);
  471.         setwattr(&wattr);
  472.     }
  473.     if (len < 0)
  474.         len= strlen(str);
  475.     width= TextWidth(str, 0, len);
  476.     if (drawing == NULL)
  477.         setwattr(&saveattr);
  478.     return width;
  479. }
  480.  
  481. int
  482. wcharwidth(c)
  483.     int c;
  484. {
  485.     char cbuf[1];
  486.     cbuf[0]= c;
  487.     return wtextwidth(cbuf, 1);
  488. }
  489.  
  490. /* TEXT DRAWING. */
  491.  
  492. void
  493. wdrawtext(h, v, str, len)
  494.     int h, v;
  495.     char *str;
  496.     int len;
  497. {
  498.     Point pen;
  499.     
  500.     if (len < 0)
  501.         len= strlen(str);
  502.     MoveTo(h, v + baseline);
  503.     DrawText(str, 0, len);
  504.     GetPen(&pen);
  505.     if (wattr.style & TX_INVERSE) {
  506.         Rect r;
  507.         SetRect(&r, h, v, pen.h, v + lineheight);
  508.         InvertRect(&r);
  509.     }
  510. }
  511.  
  512. void
  513. wdrawchar(h, v, c)
  514.     int h, v;
  515.     int c;
  516. {
  517.     if ((wattr.style & TX_INVERSE) == 0) {
  518.         /* Attempt to optimize for appls. like dpv */
  519.         MoveTo(h, v + baseline);
  520.         DrawChar(c);
  521.     }
  522.     else {
  523.         char cbuf[1];
  524.         cbuf[0]= c;
  525.         wdrawtext(h, v, cbuf, 1);
  526.     }
  527. }
  528.  
  529. /* COORDINATE CONVERSIONS ETC. */
  530.  
  531. /* Create a rect in current window coordinates (as for getwinrect)
  532.    from a rectangle given in document coordinates.
  533.    This works both while drawing and while not drawing.
  534.    The resulting rectangle is clipped to the winrect. */
  535.  
  536. void
  537. makerect(win, pr, left, top, right, bottom)
  538.     WINDOW *win;
  539.     Rect *pr;
  540.     int left, top, right, bottom;
  541. {
  542.     Rect r;
  543.     SetRect(pr, left, top, right, bottom);
  544.     if (!drawing)
  545.         OffsetRect(pr, - win->orgh, - win->orgv);
  546.     getwinrect(win, &r);
  547.     (void) SectRect(&r, pr, pr);
  548. }
  549.  
  550. /* Retrieve the 'winrect', i.e., the contents area exclusive
  551.    of the scroll bars and grow icon.
  552.    Coordinates are in window coordinates, i.e.,
  553.    the origin is (0, 0) outside w{begin,end}drawing,
  554.    but (win->orgh, win->orgv) between calls to these routines. */
  555.  
  556. void
  557. getwinrect(win, pr)
  558.     WINDOW *win;
  559.     Rect *pr;
  560. {
  561.     *pr= win->w->portRect;
  562.     if (win->vbar != NULL)
  563.         pr->right -= BAR;
  564.     if (win->hbar != NULL)
  565.         pr->bottom -= BAR;
  566. }
  567.  
  568. /* ACTUAL DRAW ROUTINES. */
  569.  
  570. void
  571. wdrawline(h1, v1, h2, v2)
  572. {
  573.     MoveTo(h1, v1);
  574.     Line(h2-h1, v2-v1);
  575. }
  576.  
  577. void
  578. wxorline(h1, v1, h2, v2)
  579. {
  580.     MoveTo(h1, v1);
  581.     PenMode(patXor);
  582.     Line(h2-h1, v2-v1);
  583.     PenNormal();
  584. }
  585.  
  586. void
  587. wdrawbox(left, top, right, bottom)
  588.     int left, top, right, bottom;
  589. {
  590.     Rect r;
  591.     
  592.     SetRect(&r, left, top, right, bottom);
  593.     FrameRect(&r);
  594. }
  595.  
  596. void
  597. werase(left, top, right, bottom)
  598.     int left, top, right, bottom;
  599. {
  600.     Rect r;
  601.     
  602.     SetRect(&r, left, top, right, bottom);
  603.     EraseRect(&r);
  604. }
  605.  
  606. void
  607. winvert(left, top, right, bottom)
  608.     int left, top, right, bottom;
  609. {
  610.     Rect r;
  611.     
  612.     SetRect(&r, left, top, right, bottom);
  613.     InvertRect(&r);
  614. }
  615.  
  616. void
  617. wpaint(left, top, right, bottom)
  618.     int left, top, right, bottom;
  619. {
  620.     Rect r;
  621.     
  622.     SetRect(&r, left, top, right, bottom);
  623.     FillRect(&r, drawing->w->pnPat);
  624. }
  625.  
  626. void
  627. wshade(left, top, right, bottom, perc)
  628.     int left, top, right, bottom;
  629.     int perc;
  630. {
  631.     Rect r;
  632.     PatPtr p;
  633.     
  634.     perc= (perc + 12)/25;
  635.     CLIPMIN(perc, 0);
  636.     
  637.     switch (perc) {
  638.     case 0:    p = &pat0;    break;
  639.     case 1: p = &pat25;    break;
  640.     case 2: p = &pat50;     break;
  641.     case 3: p = &pat75;    break;
  642.     default: p = &pat100;    break;
  643.     }
  644.     
  645.     SetRect(&r, left, top, right, bottom);
  646.  
  647.     FillRect(&r, p);
  648. }
  649.  
  650. void
  651. wdrawcircle(h, v, radius)
  652.     int h, v;
  653.     int radius;
  654. {
  655.     Rect r;
  656.     
  657.     SetRect(&r, h-radius, v-radius, h+radius, v+radius);
  658.     FrameOval(&r);
  659. }
  660.  
  661. void
  662. wfillcircle(h, v, radius)
  663.     int h, v;
  664.     int radius;
  665. {
  666.     Rect r;
  667.     
  668.     SetRect(&r, h-radius, v-radius, h+radius, v+radius);
  669.     FillOval(&r, drawing->w->pnPat);
  670. }
  671.  
  672. void
  673. wxorcircle(h, v, radius)
  674.     int h, v;
  675.     int radius;
  676. {
  677.     Rect r;
  678.     
  679.     SetRect(&r, h-radius, v-radius, h+radius, v+radius);
  680.     InvertOval(&r);
  681. }
  682.  
  683. /* Draw counterclockwise elliptical arc.
  684.    h, v are center; hrad, vrad are half axes; ang1 and ang2 are start
  685.    and stop angles in degrees, with respect to 3 o'clock. */
  686.  
  687. void
  688. wdrawelarc(h, v, hrad, vrad, ang1, ang2)
  689. {
  690.     Rect r;
  691.     SetRect(&r, h-hrad, v-vrad, h+hrad, v+vrad);
  692.     FrameArc(&r, 90-ang1, ang1-ang2);
  693. }
  694.  
  695. /* Fill an elliptical arc */
  696.  
  697. void
  698. wfillelarc(h, v, hrad, vrad, ang1, ang2)
  699. {
  700.     Rect r;
  701.     SetRect(&r, h-hrad, v-vrad, h+hrad, v+vrad);
  702.     FillArc(&r, 90-ang1, ang1-ang2, drawing->w->pnPat);
  703. }
  704.  
  705. /* Invert an elliptical arc */
  706.  
  707. void
  708. wxorelarc(h, v, hrad, vrad, ang1, ang2)
  709. {
  710.     Rect r;
  711.     SetRect(&r, h-hrad, v-vrad, h+hrad, v+vrad);
  712.     InvertArc(&r, 90-ang1, ang1-ang2);
  713. }
  714.  
  715. /* Draw a polyline of n-1 connected segments (not necessarily closed).
  716.    This means n points.  Points are given as an array of POINTs. */
  717.  
  718. void
  719. wdrawpoly(n, points)
  720.     int n;
  721.     POINT *points;
  722. {
  723.     if (--n > 0) {
  724.         MoveTo(points[0].h, points[0].v);
  725.         do {
  726.             points++;
  727.             LineTo(points[0].h, points[0].v);
  728.         } while (--n > 0);
  729.     }
  730. }
  731.  
  732. /* Fill a polygon of n points */
  733.  
  734. void
  735. wfillpoly(n, points)
  736.     int n;
  737.     POINT *points;
  738. {
  739.     PolyHandle ph = OpenPoly();
  740.     wdrawpoly(n, points);
  741.     ClosePoly();
  742.     FillPoly(ph, drawing->w->pnPat);
  743.     DisposHandle((Handle)ph);
  744. }
  745.  
  746. /* Invert a polygon of n points */
  747.  
  748. void
  749. wxorpoly(n, points)
  750.     int n;
  751.     POINT *points;
  752. {
  753.     PolyHandle ph = OpenPoly();
  754.     wdrawpoly(n, points);
  755.     ClosePoly();
  756.     InvertPoly(ph);
  757.     DisposHandle((Handle)ph);
  758. }
  759.  
  760. /* CLIPPING */
  761.  
  762. void
  763. wcliprect(left, top, right, bottom)
  764.     int left, top, right, bottom;
  765. {
  766.     Rect r1, r2;
  767.     SetRect(&r1, left, top, right, bottom);
  768.     getwinrect(drawing, &r2);
  769.     SectRect(&r1, &r2, /*dst:*/ &r2);
  770.     ClipRect(&r2);
  771.  
  772. }
  773.  
  774. void
  775. wnoclip()
  776. {
  777.     Rect r;
  778.     getwinrect(drawing, &r);
  779.     ClipRect(&r);
  780. }
  781.  
  782. /* COLOR */
  783.  
  784. COLOR
  785. wgetfgcolor()
  786. {
  787.     return _w_fgcolor;
  788. }
  789.  
  790. COLOR
  791. wgetbgcolor()
  792. {
  793.     return _w_bgcolor;
  794. }
  795.  
  796. void
  797. wsetfgcolor(color)
  798.     COLOR color;
  799. {
  800.     _w_fgcolor = color;
  801.     if (drawing)
  802.         _w_usefgcolor(color);
  803. }
  804.  
  805. void
  806. wsetbgcolor(color)
  807.     COLOR color;
  808. {
  809.     _w_bgcolor = color;
  810.     if (drawing)
  811.         _w_usebgcolor(color);
  812. }
  813.  
  814. void
  815. _w_usefgcolor(color)
  816.     COLOR color;
  817. {
  818.     ForeColor((short)color);
  819.     switch (((color >> 16) + 32) / 64) {
  820.     case 0:
  821.         PenPat(pat100);
  822.         break;
  823.     case 1:
  824.         PenPat(pat75);
  825.         break;
  826.     case 2:
  827.         PenPat(pat50);
  828.         break;
  829.     case 3:
  830.         PenPat(pat25);
  831.         break;
  832.     case 4:
  833.         PenPat(pat0);
  834.         break;
  835.     }
  836. }
  837.  
  838. void
  839. _w_usebgcolor(color)
  840.     COLOR color;
  841. {
  842.     BackColor((short)color);
  843. }
  844.